using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using Dimebrain.TweetSharp.Core.Extensions;

namespace Dimebrain.TweetSharp.Core.Web.Query
{
    partial class WebQueryBase
    {
        protected virtual HttpWebRequest BuildMultiPartFormRequest(string url, IEnumerable<HttpPostParameter> parameters, out byte[] bytes)
        {
            var boundary = Guid.NewGuid().ToString();
            var request = (HttpWebRequest) WebRequest.Create(url);
            
#if !SILVERLIGHT
            // todo should be able to remove these anyway
            request.PreAuthenticate = true;
            request.AllowWriteStreamBuffering = true;
#endif
            request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            request.Method = "POST";
            
            var contents = BuildMultiPartFormRequestParameters(boundary, parameters);
            var payload = contents.ToString();
            
            bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(payload);
            
#if !SILVERLIGHT
            request.ContentLength = bytes.Length;
#endif
            return request;
        }

        protected static StringBuilder BuildMultiPartFormRequestParameters(string boundary, IEnumerable<HttpPostParameter> parameters)
        {
            var header = string.Format("--{0}", boundary);
            var footer = string.Format("--{0}--", boundary);
            var contents = new StringBuilder();

            foreach(var parameter in parameters)
            {
                contents.AppendLine(header);
                switch (parameter.Type)
                {
                    case HttpPostParameterType.File:
                    {
#if !Smartphone && !SILVERLIGHT
                        var fileBytes = File.ReadAllBytes(parameter.FilePath);
#else
                        byte[] fileBytes;
                        var info = new FileInfo(parameter.FilePath);
                        using (var fs = new FileStream(parameter.FilePath, FileMode.Open, FileAccess.Read))
                        {
                            using (var br = new BinaryReader(fs))
                            {
                                fileBytes = br.ReadBytes((int)info.Length);
                            }
                        }
#endif
                        const string fileMask = "Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"";
                        var fileHeader = fileMask.FormatWith(parameter.Name,parameter.FileName);
                        var fileData = Encoding.GetEncoding("iso-8859-1").GetString(fileBytes, 0, fileBytes.Length);

                        contents.AppendLine(fileHeader);
                        contents.AppendLine("Content-Type: {0}".FormatWith(parameter.ContentType.ToLower()));
                        contents.AppendLine();
                        contents.AppendLine(fileData);

                        break;
                    }
                    case HttpPostParameterType.Field:
                    {
                        contents.AppendLine("Content-Disposition: form-data; name=\"{0}\"".FormatWith(parameter.Name));
                        contents.AppendLine();
                        contents.AppendLine(parameter.Value);
                        break;
                    }
                }
            }

            contents.AppendLine(footer);
            return contents;
        }
    }
}